package pso;

import java.util.*;

public class PSO {
	//variable
	static int gen = 100;
	static int length = 300;
	//
	static double BGx;
	static double BGy;
	static int BGLocal;	
	//array
	static double[] px = new double[length]; //local position
	static double[] py = new double[length];
	static double[] cost = new double[length];
	static double[] Bpx = new double[length]; //local Best
	static double[] Bpy = new double[length];
	static double[] vx = new double[length];//verschiebung
	static double[] vy = new double[length];

	static Random rd = new Random();
	
	//initial 
	public static void main(String[] args){
		for(int i=0;i<length;i++){
			px[i] = (rd.nextInt(10));
			py[i] = (rd.nextInt(10));
			cost[i] = fun(px[i],py[i]);
			
			vx[i] = Math.random();
			vy[i] = Math.random();
		}
		//Find min position
		for(int j=0;j<gen;j++){
			BGLocal = F_min();
			BGx = px[BGLocal];
			BGy = py[BGLocal];
			//count local best
			for(int i=0;i<length;i++){
				B_local(i);
			}
			//count ver
			for(int i=0;i<length;i++){
				vel_pos(i);
			}
			
			//PSO x(t+1) = x(t) + v(t+1)
			//restrict
			for(int i=0;i<length;i++){
				//if(){}
				//else{
					px[i] = (px[i] + vx[i]);
					py[i] = (py[i] + vy[i]);
				//}
			}
			
		}
		
		int Ans = F_min();
		double ax = px[Ans];
		double ay = py[Ans];
		double Min = fun(ax,ay);
		
		//Output
		System.out.println("------------------------------------");
		System.out.println("X:" + ax);
		System.out.println("Y:" + ay);
		System.out.println("Min:" + Min);
		System.out.println("------------------------------------");			
	}
	//Function
	public static double fun(double x , double y){
		return 0.5 + (Math.sin(Math.sqrt((Math.pow(x, 2) + Math.pow(y, 2)))) - 0.5) / 1 + 0.1*((Math.pow(x, 2) + Math.pow(y, 2)));
	}
	//Find min method
	public static int F_min(){
		double min = 999;
		double temp =0;
		int gi = 0;
		
		for(int i=0;i<gen;i++){
			temp = fun(px[i],py[i]);
			
			if(temp<min){
				min = temp;
				gi = i;
			}
		}
		return gi;
	}
	//find Local Best method x,y
	public static void B_local(int i){
		double temp = 0;
		temp = fun(px[i],py[i]);
	    if(temp < cost[i]){
	    	Bpx[i] = px[i];
	    	Bpy[i] = py[i];
	    }
	    cost[i] = temp;
	}
	//Update - rate
	public static void vel_pos(int i){
		vx[i] = (0.8*vx[i])+(2.1*Math.random()*(Bpx[i]-px[i]))+(2.1*Math.random()*(BGx-px[i]));
		vy[i] = (0.8*vy[i])+(2.1*Math.random()*(Bpy[i]-py[i]))+(2.1*Math.random()*(BGy-py[i]));
	}
}